package com.weilele.mvvm.view

import android.content.Context
import android.util.AttributeSet
import android.view.View
import com.weilele.mvvm.utils.activity.hadScrollToTop
import kotlin.math.abs


/**
 * 当子view 不能再向下滑动的时候
 * 整个视图开始向下滑动
 * 可以做下滑隐藏对话框
 * 可以扩展上拉刷新下拉加载的view
 */
@Deprecated("代码只是留给自己做参考")
private class ScrollDownView : ChildUnConsumedView {
    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    init {
        canDragBottom = false
        canDragStart = false
        canDragEnd = false
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        addOnChildUnConsumedListener(::onChildUnConsumedListener)
    }

    private fun onChildUnConsumedListener(
        parent: View,
        target: View,
        unConsumedX: Float,
        unConsumedY: Float,
        isScrolling: Boolean,
        hasFling: Boolean,
        type: Int,
    ) {
        scrollTo(0, -unConsumedY.toInt())
        if (!isScrolling) {
            stopListener?.invoke(parent, target, unConsumedY)
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        removeOnChildUnConsumedListener(::onChildUnConsumedListener)
    }

    private var stopListener: Function3<@ParameterName("parent") View/*父view*/,
            @ParameterName("target") View/*子view*/,
            @ParameterName("unConsumedY") Float/*移动距离*/,
            Unit>? = null
    private var onFlingListener: Function3<@ParameterName("target") View,
            @ParameterName("velocityX") Float,
            @ParameterName("velocityY") Float,
            Unit>? = null

    fun setOnStopScrollListener(
        l: Function3<@ParameterName("parent") View/*父view*/,
                @ParameterName("target") View/*子view*/,
                @ParameterName("unConsumedY") Float/*移动距离*/,
                Unit>?
    ) {
        stopListener = l
    }

    fun setOnFlingListener(
        l: Function3<@ParameterName("target") View,
                @ParameterName("velocityX") Float,
                @ParameterName("velocityY") Float,
                Unit>?
    ) {
        onFlingListener = l
    }

    var maxAnimDuration = 200L

    /**
     * 停止滑动
     * 可以调用这个方法处理一下最后的滑动
     * isReset true 复位，false 隐藏
     * offY：已经滚动的距离
     */
    fun stop(
        isReset: Boolean,
        oldOffY: Int = scrollY,
        totalY: Int = -height,
        finishListener: Function1<@ParameterName("isReset") Boolean, Unit>? = null
    ) {
        if (oldOffY == 0) {
            finishListener?.invoke(isReset)
            return
        }
        val offY = abs(oldOffY)
        isEnabled = false
        val durationACopy = maxAnimDuration.toFloat() / abs(totalY)
        val duration = if (isReset) {
            (offY * durationACopy).toLong()
        } else {
            (abs((totalY - oldOffY)) * durationACopy).toLong()
        }
        animate().cancel()
        val finalY = if (isReset) 0 else totalY
        animate()
            .setDuration(duration)
            .setUpdateListener {
                //0-1f
                val jindu = it.animatedFraction
                scrollTo(0, (oldOffY + (finalY - oldOffY) * jindu).toInt())
            }
            .withEndAction {
                initAll()
                finishListener?.invoke(isReset)
                isEnabled = true
            }
            .start()
    }

    override fun onNestedPreFling(target: View, velocityX: Float, velocityY: Float): Boolean {
        if (velocityY < 0 && target.hadScrollToTop()) {//向下发生惯性
            onFlingListener?.invoke(target, velocityX, velocityY)
        }
        return super.onNestedPreFling(target, velocityX, velocityY)
    }
}